package com.game;

import javax.microedition.khronos.opengles.GL10;

import media.sound.GameSound;
import media.sound.SoundBackground;
import system.Constants;
import system.Device;
import system.Graphics;
import system.KeyBoard;
import android.content.Context;

import com.game.state.About;
import com.game.state.AskForSound;
import com.game.state.Exit;
import com.game.state.GameOver;
import com.game.state.GameWin;
import com.game.state.Help;
import com.game.state.HighScore;
import com.game.state.InGame;
import com.game.state.InGameMenu;
import com.game.state.Loading;
import com.game.state.MainMenu;
import com.game.state.Option;
import com.game.state.QuitMission;
import com.game.state.ShowLogo;
import com.game.state.Splash;
import com.game.state.State;

public class GamePlay implements Constants {
	// ------------------------------------------------------------
	// / Variable Declare
	// ------------------------------------------------------------
	private int m_stateBegin = GameState.InGame;
	private final int m_maxSubState = 4;
	private int m_iState = 0;
	private State[] m_arrState = new State[m_maxSubState];
	private int m_iMilisecPerFrame;
	private double m_dLastRender;

	// ------------------------------------------------------------
	// / Constructor
	// ------------------------------------------------------------
	GamePlay(Context context, GL10 gl, int w, int h) {
		Graphics.SetGraphics(gl);
		Device.SetContext(context);
		Device.SetSize(w, h);
		for (int i = 0; i < m_maxSubState; i++)
			this.m_arrState[i] = null;
		this.Init();
		SetFPS(30);
	}

	// ------------------------------------------------------------
	// / Initialize state, variable
	// ------------------------------------------------------------
	private void Init() {
		GL10 gl = Graphics.GetGraphics();
		gl.glViewport(0, 0, Device.GetWidth(), Device.GetHeight());
		gl.glMatrixMode(GL10.GL_MODELVIEW);
		gl.glEnable(GL10.GL_DEPTH_TEST);
		gl.glDepthFunc(GL10.GL_LESS | GL10.GL_EQUAL);
		gl.glClearColor(0f, 0f, 0f, 1f);
		gl.glEnable(GL10.GL_CULL_FACE);
		gl.glFrontFace(GL10.GL_CCW);
		gl.glCullFace(GL10.GL_BACK);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glEnable(GL10.GL_ALPHA_TEST);
		gl.glEnable(GL10.GL_BLEND);
		gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);

		this.SwitchState(m_stateBegin);
	}

	public void Render() {
		double currentTime = System.currentTimeMillis();
//		if (currentTime - m_dLastRender >= m_iMilisecPerFrame
//				|| !m_arrState[m_iState].IsReadyResource()) {
			m_dLastRender = currentTime;
			m_arrState[m_iState].Update(this);
			m_arrState[m_iState].Render();
//		}
	}

	public void Exit() {
		SoundBackground s =GameSound.GetBgSound();
		if (s != null)
			GameSound.GetBgSound().Stop();
	}

	// ------------------------------------------------------------
	// / Switch from current state to new state
	// / @param the ID of new state
	// / @return
	// ------------------------------------------------------------
	public void SwitchState(int newState) {
		KeyBoard.ClearKey();
		for (int i = 0; i <= m_iState; i++) {
			this.Destroy(m_arrState[i]);
			m_arrState[i] = null;
		}
		m_iState = 0;
		m_arrState[m_iState] = this.InitState(newState);

	}

	public void SwitchSubState(int newState) {
		KeyBoard.ClearKey();
		m_iState++;
		if (m_iState >= m_maxSubState) {
			m_iState = m_maxSubState - 1;
		}
		m_arrState[m_iState] = this.InitState(newState);
	}

	// ------------------------------------------------------------
	// / Was called when switch state
	// / @param the ID of State was destroyed
	// / @return
	// ------------------------------------------------------------
	private void Destroy(State currState) {
		if (currState != null) {
			currState.Destroy();
		}
	}

	private State InitState(int newState) {
		State currState = null;
		switch (newState) {
		case GameState.ShowLogo:
			currState = new ShowLogo();
			break;
		case GameState.Splash:
			currState = new Splash();
			break;
		case GameState.AskForSounds:
			currState = new AskForSound();
			break;
		case GameState.MainMenu:
			currState = new MainMenu();
			break;
		case GameState.HighScore:
			currState = new HighScore();
			break;
		case GameState.Options:
			currState = new Option();
			break;
		case GameState.About:
			currState = new About();
			break;
		case GameState.Help:
			currState = new Help();
			break;
		case GameState.InGame:
			currState = new InGame();
			break;
		case GameState.InGameMenu:
			currState = new InGameMenu();
			break;
		case GameState.GameWin:
			currState = new GameWin();
			break;
		case GameState.GameOver:
			currState = new GameOver();
			break;
		case GameState.Exit:
			currState = new Exit();
			break;
		case GameState.QuitMission:
			currState = new QuitMission();
			break;
		default:
			break;
		}
		if (currState != null)
			currState.Init();
		return currState;
	}

	// ------------------------------------------------------------
	// / Return to super state
	// ------------------------------------------------------------
	public boolean ResumeState() {
		if (m_iState > 0) {
			this.Destroy(m_arrState[m_iState]);
			m_arrState[m_iState] = null;
			m_iState--;
			return true;
		}
		return false;
	}

	// ------------------------------------------------------------
	// / Getter and setter function
	// ------------------------------------------------------------
	public int getMenuLevel() {
		return m_iState;
	}

	public void SetFPS(int fps) {
		m_iMilisecPerFrame = 1000 / fps;
	}

	public int GetFPS() {
		return 1000 / m_iMilisecPerFrame;
	}
}
